/** @file MoveCommand.h
    @class MoveCommand
    @brief Command that moves a game object
*/
#ifndef __MoveCommand_h_
#define __MoveCommand_h_

#include "Command.h"
class MoveCommand : public Command {
public:
	/**
	* @brief The constructor
	*/
	MoveCommand (float x, float y, float z, unsigned int playerId)
		: Command(playerId), m_moveX(x), m_moveY(y), m_moveZ(z) {}
	
	/**
	* @brief The empty constructor
	*/	
	MoveCommand() {}
	
	/**
	* @brief The destructor
	*/
	virtual ~MoveCommand (void) {}
	
	/**
	* @brief Executs the command on argument model
	*/
	virtual bool execute(Model *model) {
		GameObject *gameObject = model->getByID(getPlayerId());
		if ( gameObject == NULL) {
			return false;
		} else {
			gameObject->move(m_moveX, m_moveY, m_moveZ);
			return true;
		}
	}
	
	/**
	* @brief Saves the command to a output file stream
	*/
	virtual void save(ofstream &ofs) {
		int i = MOVECOMMAND;
		ofs.write((char*) &i, sizeof(int));
		Command::save(ofs);
		ofs.write((char*) &m_moveX, sizeof(float));
		ofs.write((char*) &m_moveY, sizeof(float));
		ofs.write((char*) &m_moveZ, sizeof(float));
  }

	/**
	* @brief Loads a command from a input file stream
	*/
  virtual void load(ifstream &ifs) {
		Command::load(ifs);
		ifs.read((char*) &m_moveX, sizeof(float));
		ifs.read((char*) &m_moveY, sizeof(float));
		ifs.read((char*) &m_moveZ, sizeof(float));
  }

	/**
	* @brief Saves the command to a bit stream
	*/
  virtual void save(RakNet::BitStream &ofs) {
		int i = MOVECOMMAND;
		ofs.Write((char*) &i, sizeof(int));
		Command::save(ofs);
		ofs.Write((char*) &m_moveX, sizeof(float));
		ofs.Write((char*) &m_moveY, sizeof(float));
		ofs.Write((char*) &m_moveZ, sizeof(float));
  }

	/**
	* @brief Loads a command from a bit stream
	*/
  virtual void load(RakNet::BitStream &ifs) {
		Command::load(ifs);
		ifs.Read((char*) &m_moveX, sizeof(float));
		ifs.Read((char*) &m_moveY, sizeof(float));
		ifs.Read((char*) &m_moveZ, sizeof(float));
  }

private:
	/**
	* @brief Movement in x direction
	*/
	float m_moveX;
	
	/**
	* @brief Movement in y direction
	*/
	float m_moveY;
	
	/**
	* @brief Movement in z direction
	*/
	float m_moveZ;
	
};

#endif